<!DOCTYPE html>
<html lang="zh-Hans">

<!-- Head tag -->
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!--Description-->
    
        <meta name="description" content="Note">
    

    <!--Author-->
    
        <meta name="author" content="兰陵忧患生">
    

    <!-- Title -->
    
    <title>Maven 实战 | Lan</title>

    <!-- Bootstrap Core CSS -->
    <link href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet"
      href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.12.0/build/styles/default.min.css">
    <script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.12.0/build/highlight.min.js"></script>

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/css/style.css">

    <!-- Custom Fonts -->
    <link href="//cdn.bootcss.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href='//fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>

    <!-- Content -->
    <section class="article-container">
<!-- Back Home -->
<a class="nav-back" href="/">
    <i class="fa fa-puzzle-piece"></i>
</a>

<!-- Page Header -->
<header class="intro-header">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="post-heading">
                    <h1>Maven 实战</h1>
                </div>
            </div>
        </div>
    </div>
</header>

<!-- Post Content -->
<article>
    <div class="container">
        <div class="row">
            <!-- TOC -->
            <div class="toc-article col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Maven-安装和配置"><span class="toc-text">Maven 安装和配置</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#设置-HTTP-代理"><span class="toc-text">设置 HTTP 代理</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Maven-安装最佳实践"><span class="toc-text">Maven 安装最佳实践</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Maven-使用入门"><span class="toc-text">Maven 使用入门</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#编写-POM"><span class="toc-text">编写 POM</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#编写主代码"><span class="toc-text">编写主代码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#编写测试代码"><span class="toc-text">编写测试代码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#打包和运行"><span class="toc-text">打包和运行</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#使用-Archetype-生成项目骨架"><span class="toc-text">使用 Archetype 生成项目骨架</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#背景案例"><span class="toc-text">背景案例</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#坐标和依赖"><span class="toc-text">坐标和依赖</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#依赖的配置"><span class="toc-text">依赖的配置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#依赖范围"><span class="toc-text">依赖范围</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#传递性依赖"><span class="toc-text">传递性依赖</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#传递性依赖和依赖范围"><span class="toc-text">传递性依赖和依赖范围</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#依赖调解"><span class="toc-text">依赖调解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#可选依赖"><span class="toc-text">可选依赖</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#最佳实践"><span class="toc-text">最佳实践</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#排除依赖"><span class="toc-text">排除依赖</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#归类依赖"><span class="toc-text">归类依赖</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#优化依赖"><span class="toc-text">优化依赖</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#仓库"><span class="toc-text">仓库</span></a></li></ol>
</div>

            <!-- Post Main Content -->
            <div class="post-content col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <h1 id="Maven-安装和配置"><a href="#Maven-安装和配置" class="headerlink" title="Maven 安装和配置"></a>Maven 安装和配置</h1><h2 id="设置-HTTP-代理"><a href="#设置-HTTP-代理" class="headerlink" title="设置 HTTP 代理"></a>设置 HTTP 代理</h2><pre><code class="SHELL">ping repo1.maven.org
telnet 218.14.227.197 3128
</code></pre>
<ul>
<li>代理配置</li>
</ul>
<pre><code class="XML">// ~/.m2/settings.xml

&lt;settings&gt;
...
&lt;proxies&gt;
&lt;proxy&gt;
&lt;id&gt;my-proxy&lt;/id&gt;
&lt;active&gt;true&lt;/active&gt; // 表示 true 激活
&lt;protocol&gt;http&lt;/protocol&gt; // 表示使用的代理协议
&lt;host&gt;218.14.227.197&lt;/host&gt;
&lt;port&gt;3128&lt;/port&gt;
&lt;! --
&lt;username&gt;***&lt;/username&gt;
&lt;password&gt;***&lt;/password&gt;
&lt;nonProxyHosts&gt;repository.mycom.com|*.google.com&lt;/nonProxyHosts&gt; // 哪些主机名不需要代理
-- &gt;
&lt;/proxy&gt;
&lt;/proxies&gt;
...
&lt;/settings&gt;
</code></pre>
<h2 id="Maven-安装最佳实践"><a href="#Maven-安装最佳实践" class="headerlink" title="Maven 安装最佳实践"></a>Maven 安装最佳实践</h2><ul>
<li>设置 MAVEN_OPTS 环境变量，需要设置为 <code>-Xms128m-Xmx512m</code>，因为 Java 默认的最大可用内存往往不能够满足 Maven 运行的需要。</li>
<li>配置用户范围的 ~/.m2/settings.xml</li>
<li><p>不要使用 IDE 内嵌的 Maven</p>
<ul>
<li>内嵌的版本和命令行的版本可能不一致。</li>
</ul>
</li>
</ul>
<h1 id="Maven-使用入门"><a href="#Maven-使用入门" class="headerlink" title="Maven 使用入门"></a>Maven 使用入门</h1><h2 id="编写-POM"><a href="#编写-POM" class="headerlink" title="编写 POM"></a>编写 POM</h2><pre><code class="XML">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;http://maven/apache.org/POM/4.0.0
http://maven.apache/org/maven-v4_0_0.xsd&quot;&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; // POM 模型的版本
&lt;groupId&gt;com.juvenxu.mvnbook&lt;/groupId&gt; // 组
&lt;artifactId&gt;hello-world&lt;/artifactId&gt; // 组中的唯一 ID
&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
&lt;name&gt;Maven Hello World Project&lt;/name&gt; // 项目名称
&lt;/project&gt;
</code></pre>
<h2 id="编写主代码"><a href="#编写主代码" class="headerlink" title="编写主代码"></a>编写主代码</h2><ul>
<li>项目主代码位于 <code>src/main/java</code></li>
</ul>
<pre><code class="terminal">mvn clean compile
   clean:clean // 删除 target/ 目录
   resources:resources
   compiler:compile // 将项目主代码编译至 target/classes 目录
</code></pre>
<h2 id="编写测试代码"><a href="#编写测试代码" class="headerlink" title="编写测试代码"></a>编写测试代码</h2><ul>
<li>Maven 项目中默认的测试代码目录是 <code>src/test/java</code></li>
</ul>
<pre><code class="XML">...
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;junit&lt;/groupId&gt;
&lt;artifactId&gt;junit&lt;/artifactId&gt;
&lt;version&gt;4.7&lt;/version&gt;
&lt;scope&gt;test&lt;/scope&gt; // 依赖范围为 test 表示只对测试有效
&lt;/dependency&gt;
&lt;/dependencies&gt;
...
</code></pre>
<ul>
<li>groupId, artifactId 和 version 是任何一个 Maven 项目最基本的坐标。</li>
<li><p>典型的单元测试包含三个步骤</p>
<ul>
<li>准备测试类及数据</li>
<li>执行要测试的行为</li>
<li>检查结果</li>
</ul>
</li>
<li><p>约定，执行测试的方法都以 test 开头</p>
</li>
</ul>
<pre><code class="terminal">mvn clean test
    clean:clean
    resources:resources
    compiler:compile
    resources:testResources
    compiler:testCompile // 在 target/test-classes 下生成了二进制文件
    surefire:test // 负责执行测试的插件
</code></pre>
<pre><code class="XML">// 配置 maven-compiler-plugin 支持 Java5
&lt;project&gt;
...
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;source&gt;1.5&lt;/source&gt;
&lt;target&gt;1.5&lt;/target&gt;
&lt;/configuraction&gt;
&lt;/plugins&gt;
&lt;/plugin&gt;
&lt;/build&gt;
...
&lt;/project&gt;
</code></pre>
<h2 id="打包和运行"><a href="#打包和运行" class="headerlink" title="打包和运行"></a>打包和运行</h2><pre><code class="terminal">// 打包
mvn clean package
    jar:jar // 负责打包

// 根据 artifact-version.jar 规则进行命名
// 还可以使用 finalName 来自定义该文件的名称

// 引用
mvn clean install
    install:install // 将项目输出的 jar 安装到了 Maven 本地仓库中
</code></pre>
<ul>
<li><p>执行 test 之前是会先执行 compile 的，执行 package 之前是会先执行 test 的，而类似地，install 之前会执行 package</p>
</li>
<li><p>因为带有 main 方法的类信息是不会添加到 mainfest 中，为了生成可执行的 jar 文件，需要借助 maven-shade-plugin </p>
</li>
</ul>
<pre><code class="XML">&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
&lt;version&gt;1.2.1&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;phase&gt;package&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;shade&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;transformers&gt;
&lt;transformer implementation=&quot;org.apache.maven.plugins.shade.resource.ManifestResourceTramsformer&quot;&gt;
&lt;mainClass&gt;com.juvenxu.mvnbook.helloworld.HelloWorld&lt;/mainClass&gt;
&lt;/transformer&gt;
&lt;/transformers&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;

// plugin 位置位于在 POM 中 &lt;project&gt;&lt;build&gt;&lt;plugins&gt; 下面
</code></pre>
<h2 id="使用-Archetype-生成项目骨架"><a href="#使用-Archetype-生成项目骨架" class="headerlink" title="使用 Archetype 生成项目骨架"></a>使用 Archetype 生成项目骨架</h2><ul>
<li><p>Maven 约定</p>
<ul>
<li>在项目的根目录中放置 pom.xml</li>
<li>在 src/main/java 目录中放置项目的主代码</li>
<li>在 src/test/java 中放置项目的测试代码</li>
</ul>
</li>
<li><p>我们称这些基本的目录结构和 pom.xml 文件内容称为项目的骨架。</p>
</li>
</ul>
<pre><code class="XML">mvn archetype:generate
</code></pre>
<h1 id="背景案例"><a href="#背景案例" class="headerlink" title="背景案例"></a>背景案例</h1><pre><code class="text">com.juvenxu.mvnbook.account.service // 系统的核心，封装了所有下层细节，对外暴露简单的接口  Facade 模式
com.juvenxy.mvnbook.account.web // 该模块包含所有与 web 相关的内容，包括 jsp,Servlet, web.xml
com.juvenxy.mvnbook.account.persist // 处理信息的持久化
com.jubenxy.mvnbook.account.captcha // 处理验证码的 key 生成，图片生成
com.juvenxy.mvnbook.account.email // 处理邮件服务的配置，激活邮件的编写和发送
</code></pre>
<h1 id="坐标和依赖"><a href="#坐标和依赖" class="headerlink" title="坐标和依赖"></a>坐标和依赖</h1><ul>
<li>Maven 坐标的元素包括 groupId, artifactId, version, packaging, classifier</li>
<li><p>Maven 内置了一个<a href="http://repo1/maven/org/maven2" target="_blank" rel="external">中央仓库</a></p>
</li>
<li><p>groupId 定义当前 Maven 项目隶属的实际项目。和 Java 包名的表示方式，通常与域名反向一一对应。（org.sonatype.nexus）</p>
</li>
<li>artifactId 该元素定义实际项目中的一个 Maven 项目（模块），推荐的做法是使用实际项目名称作为 artifactId 的前缀。方便寻找时机构件。</li>
<li>version 该元素定义 Maven 项目当前所处的版本。</li>
<li><p>packaging 该元素定义 Maven 项目的打包方式。</p>
<ul>
<li>打包方式通常与所生成构件的文件扩展名对应。（jar 打包方式，war 打包方式）不过这不是绝对的。</li>
<li>打包方式会影响到构建的生命周期。</li>
<li>不定义 packaging 的时候，Maven 会使用默认值 jar</li>
</ul>
</li>
<li><p>classifier 该元素用来帮助定义构建输出的一些附属构建。不能直接定义项目的 classifier ，附属的插件帮助生成。</p>
</li>
<li><p>项目构件的文件名是与坐标相对应的，一般的规则为 artifactid-version[-classifier].packaging（ [-classifier] 表示可选 ）</p>
</li>
<li><p>packaging 并非一定与构件扩展名对应。</p>
</li>
<li><p>mvn clean test 执行测试，Maven 会编译主代码和测试代码，并执行测试。</p>
</li>
<li>mvn clean install 执行编译，测试，打包等工作。最后将项目生成的构件安装到本地仓库中。</li>
</ul>
<h2 id="依赖的配置"><a href="#依赖的配置" class="headerlink" title="依赖的配置"></a>依赖的配置</h2><pre><code class="XML">&lt;project&gt;
...
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;artifactId&gt;&lt;/artifactId&gt;
&lt;type&gt;&lt;/type&gt;
&lt;scope&gt;&lt;/scope&gt;
&lt;optional&gt;&lt;/optional&gt;
&lt;exclusions&gt;
&lt;exclustion&gt;
...
&lt;/exclusion&gt;
...
&lt;/exclusions&gt;
&lt;/dependency&gt;
...
&lt;/dependencies&gt;
...
&lt;/project&gt;
</code></pre>
<ul>
<li><p>根元素 project 下的 dependencies 可以包含一个或者多个 dependency 元素，以声明一个或者多个项目依赖。</p>
</li>
<li><p>每个依赖可以包含的元素有</p>
<ul>
<li>groupId,artifactId 和 version 依赖的基本坐标，对于任何一个依赖来说，基本坐标是最重要的，Maven 根据坐标才能找到需要的依赖。</li>
<li>type 依赖的类型。对应于项目坐标定义的 packaging。大部分情况下，该元素不必声明，其默认值为 jar</li>
<li>scope 依赖的范围</li>
<li>optional 标记依赖是否可选</li>
<li>exclusions 用来排除传递性依赖</li>
</ul>
</li>
</ul>
<h2 id="依赖范围"><a href="#依赖范围" class="headerlink" title="依赖范围"></a>依赖范围</h2><ul>
<li><p>JUnit 依赖的测试范围是 test，测试范围用元素 scope 表示。</p>
</li>
<li><p>依赖范围哦就是用来控制依赖与这三种 classpath（编译 classpath，测试 classpath，运行 classpath）</p>
<ul>
<li>compile 编译依赖范围。如果没有指定，就会默认使用该依赖范围。使用此依赖范围的 Maven 依赖，对于编译，测试，运行三种 classpath 都有效。</li>
<li>test 测试依赖范围。使用此依赖范围的 Maven 依赖，只对于测试 classpath 有效。</li>
<li>provided 已提供依赖范围。对于编译和测试 class-path 有效，但在运行时无效。典型的例子是 servlet-api ，编译和测试项目的时候需要该依赖，但在运行项目的时候，由于容器已经提供，就不需要 Maven 重复地引入一遍</li>
<li>runtime 运行时依赖范围。对于测试和运行 class-path 有效，但在编译主代码时无效。典型的例子是 JDBC 驱动实现，项目主代码的编译只需要 JDK 提供的 JDBC 接口，只有在执行测试或者运行项目的时候才需要实现上述接口的具体 JDBC 驱动。</li>
<li><p>system 系统依赖范围。和 provided 依赖范围完全一致。但是，使用 system 范围的依赖时必须通过 systemPath 元素显示地指定依赖文件的路径。（由于此类依赖不是通过 Maven 仓库解析的，而且往往于本机系统绑定，可能造成构建的不可移植，谨慎使用）</p>
<ul>
<li><p>systemPath 元素可以引用环境变量。</p>
<pre><code class="XML">&lt;dependency&gt;
&lt;groupId&gt;javax.sql&lt;/groupId&gt;
&lt;artifactId&gt;jdbc-stdext&lt;/artifactId&gt;
&lt;version&gt;2.0&lt;/version&gt;
&lt;systemPath&gt;${java.home}/lib/rt.jar&lt;/systemPath&gt;
&lt;/dependency&gt;
</code></pre>
</li>
</ul>
</li>
<li><p>import (Maven 2.0.9 及以上) 导入依赖范围。该该依赖范围不会对三种 classpath 产生实际的影响。</p>
</li>
</ul>
</li>
</ul>
<h2 id="传递性依赖"><a href="#传递性依赖" class="headerlink" title="传递性依赖"></a>传递性依赖</h2><ul>
<li>account-mail 有一个 compile 范围的 spring-core 依赖， spring-core 有一个 compile 范围的 commons-logging 依赖，那么 commons-logging 就会称为 account-email 的 compile 范围依赖， commons-logging 是 account-email 的一个传递性依赖。</li>
<li>Maven 会解析各个直接依赖的 POM，将那些必要的间接依赖，以传递性依赖的形式引入到当前的项目中。</li>
</ul>
<h3 id="传递性依赖和依赖范围"><a href="#传递性依赖和依赖范围" class="headerlink" title="传递性依赖和依赖范围"></a>传递性依赖和依赖范围</h3><ul>
<li>当第二直接依赖的范围是 compile 的时候，传递性依赖的范围与第一直接依赖的范围一致</li>
<li>当第二直接依赖的范围是 test 的时候，依赖不会得以传递</li>
<li>当第二直接依赖的范围是 provided 的依赖，且传递性依赖的范围同样为 provided</li>
<li>当第二直接依赖的范围是 runntime 的时候，传递性依赖的范围与第一直接依赖的范围一致，但 compile 例外，此时传递性依赖的范围为 runtime</li>
</ul>
<h2 id="依赖调解"><a href="#依赖调解" class="headerlink" title="依赖调解"></a>依赖调解</h2><ul>
<li>Maven 依赖调解（Dependency Mediation）的第一原则是：路径最近者优先。</li>
<li>从 Maven2.0.9 开始，Maven 定义了依赖调解的第二原则：第一声明者优先。</li>
</ul>
<h2 id="可选依赖"><a href="#可选依赖" class="headerlink" title="可选依赖"></a>可选依赖</h2><ul>
<li>可能项目 B 实现了两个特性，其中的特性一依赖于 X，特性二依赖于 Y ，而且这两个特性是互斥的，用户不能同时使用两个特性</li>
</ul>
<pre><code class="XML">&lt;project&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;com.juvenxy.mvnbook&lt;/groupId&gt;
&lt;artifactId&gt;project-b&lt;/artifactId&gt;
&lt;version&gt;1.0.0&lt;/version&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;mysql&lt;groupId&gt;
&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
&lt;version&gt;5.1.10&lt;/version&gt;
&lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;postgresql&lt;/groupId&gt;
&lt;artifactId&gt;postgresql&lt;/artifactId&gt;
&lt;version&gt;8.4-701.jdbc3&lt;/version&gt;
&lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/project&gt;

// mysql-connector-java 和 postgresql 这两个依赖是可选依赖，这两个依赖不会被传递。
</code></pre>
<ul>
<li><p>可选依赖不被传递</p>
</li>
<li><p>理想的情况下，是不应该使用可选依赖的。根据单一职责性原则，一个类应该只能有一项职责。更好的做法是，为 MySQL 和 PostgreSQL 分别创建一个 Maven 项目，基于同样的 groupId 分配不同的 artifactId</p>
</li>
</ul>
<h2 id="最佳实践"><a href="#最佳实践" class="headerlink" title="最佳实践"></a>最佳实践</h2><h3 id="排除依赖"><a href="#排除依赖" class="headerlink" title="排除依赖"></a>排除依赖</h3><pre><code class="XML">&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;com.juvenxu.mvnbook&lt;/groupId&gt;
&lt;artifactId&gt;project-b&lt;/.&gt;
&lt;version&gt;1.0.0&lt;/.&gt;
&lt;exclusions&gt; // 声明排除依赖
&lt;exclusion&gt;
&lt;groupId&gt;com.juvenxu.mvnbook&lt;/groupId&gt;
&lt;artifactId&gt;project-c&lt;/artifactId&gt;
&lt;/exclusion&gt;
&lt;/exclusions&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;com.juvenxu.mvnbook&lt;/.&gt;
&lt;artifactId&gt;project-c&lt;/artifactId&gt;
&lt;version&gt;1.1.0&lt;/&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
</code></pre>
<ul>
<li>exclusions 元素声明排除依赖。声明 exclusion 的时候只需要 groupId 和 artifactId，而不要 version 元素。</li>
</ul>
<h3 id="归类依赖"><a href="#归类依赖" class="headerlink" title="归类依赖"></a>归类依赖</h3><pre><code class="XML">// Spring Framework 中的不同模块版本号
&lt;project&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;com.juven.mvnbook.account&lt;/groupId&gt;
&lt;artifactId&gt;account-mail&lt;/artifactId&gt;
&lt;name&gt;Account Email&lt;/name&gt;
&lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
&lt;properties&gt;
&lt;springframework.version&gt;2.5.6&lt;/springframework.version&gt;
&lt;/properties&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework&lt;/groupId&gt;
&lt;artifactId&gt;spring-core&lt;/artifactId&gt;
&lt;version&gt;${springframework.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework&lt;/groupId&gt;
&lt;artifactId&gt;spring-beans&lt;/artifactId&gt;
&lt;version&gt;${springframework.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework&lt;/groupId&gt;
&lt;artifactId&gt;spring-context&lt;/artifactId&gt;
&lt;version&gt;${springframework.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework&lt;/groupId&gt;
&lt;artifactId&gt;spring-context-support&lt;/artifactId&gt;
&lt;version&gt;${springframework.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/project&gt;
</code></pre>
<h3 id="优化依赖"><a href="#优化依赖" class="headerlink" title="优化依赖"></a>优化依赖</h3><ul>
<li>Maven 会自动解析所有项目的直接依赖和传递性依赖，并且根据正确判断每个依赖的范围，对于一些依赖冲突，也能进行调节，以确保任何一个构建只有唯一的版本在依赖中存在。</li>
<li>最后得到的那些依赖被称为已解析依赖。</li>
</ul>
<pre><code class="terminal">// 查看当前项目的已解析依赖
mvn dependency:list

// 依赖树
mvn dependency:tree

// 分析当前项目的依赖
mvn dependency:analyze
    Used undeclared dependencies // 指项目中使用到的，但没有显示声明的依赖。
    Unuserd undeclared dependencies // 未使用，但显示声明的依赖。应该仔细分析， dependency:analyze 只会分析编译主代码和测试代码需要用到的依赖，一些执行测试和运行时需要的依赖它发现不了。
</code></pre>
<h1 id="仓库"><a href="#仓库" class="headerlink" title="仓库"></a>仓库</h1><ul>
<li>坐标和依赖是任何一个构件在 Maven 世界上的逻辑表示方式。</li>
<li>而构件的物理表示方式是文件，Maven 通过仓库来统一管理这些文件。</li>
</ul>

 
                <!-- Meta -->
                <div class="post-meta">
                    <hr>
                    <br>
                    <div class="post-tags">
                        
                            

<a href="/tags/Maven/">#Maven</a>


                        
                    </div>
                    <div class="post-date">
                        2017 年 06 月 09 日
                    </div>
                </div>
            </div>

            <!-- Comments -->
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <!-- Disqus Comments -->


            </div>
        </div>
    </div>
</article>
</section>

    <!-- Scripts -->
    <!-- jQuery -->
<script src="//cdn.bootcss.com/jquery/2.2.1/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

<script type="text/javascript">
	hljs.initHighlightingOnLoad();
	console.log('Hexo-theme-hollow designed by zchen9 http://www.chen9.info © 2015-' + (new Date()).getFullYear());
</script>

    <!-- Google Analytics -->
    

</body>

</html>